<?php

declare(strict_types=1);

namespace app\controller\seller\verify;

use app\BaseController;
use app\model\CartFuture;
use app\model\OrgMember;
use app\service\cart\FutureInquiryService;
use app\service\factory\ResponseFactory;
use app\validate\verify\FutureSellerReplyValidate;
use InvalidArgumentException;
use think\Response;
use Throwable;

class Inquiry extends BaseController
{
    public function index(FutureInquiryService $inquiryService): Response
    {
        if ($response = $this->denyIfNotSeller()) {
            return $response;
        }

        $sellerOrgId = $this->resolveSellerOrgId();
        if ($sellerOrgId === null) {
            return json(ResponseFactory::error('未绑定卖家组织', 403), 403);
        }

        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = $this->request->only([
                'status',
                'region_id',
            ], 'get');

            if (isset($filters['status']) && is_string($filters['status']) && strpos($filters['status'], ',') !== false) {
                $filters['status'] = array_map('intval', array_filter(explode(',', $filters['status'])));
            }

            $filters['seller_org_id'] = $sellerOrgId;

            $paginator = $inquiryService->paginateRecords(
                array_filter($filters, static fn($value) => $value !== null && $value !== ''),
                $page,
                $pageSize,
                ['product']
            );

            $items = $inquiryService->formatCollection($paginator->items(), 'seller');

            return json(ResponseFactory::paginated(
                $items,
                (int) $paginator->total(),
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function read(int $id, FutureInquiryService $inquiryService): Response
    {
        if ($response = $this->denyIfNotSeller()) {
            return $response;
        }

        try {
            $record = $inquiryService->get($id);
            if ($this->resolveSellerOrgId() !== (int) $record->seller_org_id) {
                return json(ResponseFactory::error('无权访问该询价单', 403), 403);
            }

            $formatted = $inquiryService->formatRecord($record->load(['product']), 'seller');

            return json(ResponseFactory::success($formatted));
        } catch (Throwable $e) {
            $code = $e->getCode() ?: 500;
            if ($code < 100 || $code >= 600) {
                $code = 500;
            }
            return json(ResponseFactory::error($e->getMessage(), $code));
        }
    }

    public function update(int $id, FutureInquiryService $inquiryService): Response
    {
        if ($response = $this->denyIfNotSeller()) {
            return $response;
        }

        try {
            /** @var CartFuture|null $record */
            $record = CartFuture::find($id);
            if (!$record) {
                return json(ResponseFactory::error('询价单不存在', 404));
            }

            if ($this->resolveSellerOrgId() !== (int) $record->seller_org_id) {
                return json(ResponseFactory::error('无权操作该询价单', 403), 403);
            }

            $payload = $this->request->only([
                'status',
                'seller_price',
                'seller_delivery_date',
                'seller_remark',
                'seller_media',
            ], 'put');

            $this->validate($payload, FutureSellerReplyValidate::class . '.reply');

            $status = isset($payload['status']) ? (int) $payload['status'] : null;
            $sellerPrice = isset($payload['seller_price']) ? (float) $payload['seller_price'] : null;

            if ($status === null) {
                $status = ($sellerPrice !== null && $sellerPrice > 0)
                    ? CartFuture::STATUS_QUOTED
                    : CartFuture::STATUS_REJECTED;
            }

            $result = $inquiryService->reply($id, [
                'seller_id' => (int) ($this->request->user_id ?? 0),
                'status' => $status,
                'seller_price' => $sellerPrice,
                'seller_delivery_date' => $payload['seller_delivery_date'] ?? null,
                'seller_remark' => $payload['seller_remark'] ?? '',
                'seller_media' => $payload['seller_media'] ?? [],
            ]);

            return json(ResponseFactory::success(
                $inquiryService->formatRecord($result->load(['product']), 'seller'),
                '保存成功'
            ));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            $code = $e->getCode() ?: 500;
            if ($code < 100 || $code >= 600) {
                $code = 500;
            }
            return json(ResponseFactory::error($e->getMessage(), $code));
        }
    }

    private function denyIfNotSeller(): ?Response
    {
        $payload = (array) ($this->request->payload ?? []);
        $groups = $payload['groups'] ?? [];
        if (is_array($groups)) {
            foreach ($groups as $group) {
                if (is_string($group) && ((strncmp($group, 'seller', 6) === 0) || $group === 'admin')) {
                    return null;
                }
            }
        }

        return json(ResponseFactory::error('无访问权限', 403), 403);
    }

    private function resolveSellerOrgId(): ?int
    {
        $payload = (array) ($this->request->payload ?? []);
        $groups = $payload['groups'] ?? [];
        if (is_array($groups)) {
            foreach ($groups as $group) {
                if (is_string($group) && strncmp($group, 'seller_', 7) === 0) {
                    $orgId = (int) substr($group, strlen('seller_'));
                    if ($orgId > 0) {
                        return $orgId;
                    }
                }
            }
        }

        $userId = (int) ($this->request->user_id ?? 0);
        if ($userId <= 0) {
            return null;
        }

        $member = OrgMember::where('user_id', $userId)
            ->where('status', 1)
            ->find();

        return $member ? (int) $member->org_id : null;
    }
}
